import React, { Component } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { fromJS, is } from 'immutable'

import Widget from './Widget'
import themeHOC from '../../../common/themeHOC'

import { intervals } from '../intervals'
import { THEME } from '../../../../constants/constants'
import { formatValue, getContractPriceDecimalNumber } from '../../../../utils/dataUtils'

import {
  K_INTERVAL_REAL_TIME,
  subscribeKLine, unsubscribeKLine,
  getHistoryKLineData
} from '../../../../redux/actions/tradeChartAction.js'

import './trading-view.less'

@connect(state => {
  return {
    wsConnectSuccess: state.app.get('wsConnectSuccess'),
    currentContract: state.trade.market.get('currentContract'),
    contractList: state.trade.market.get('contractList'),
    currentInterval: state.trade.chart.get('currentInterval'),
    kLineData: state.trade.chart.get('kLineData')
  }
}, dispatch => {
  return bindActionCreators({
    subscribeKLine, unsubscribeKLine
  }, dispatch)
})
@themeHOC
class TradingView extends Component {
  /**
   * 初始化tradingview
   */
  initTradingView () {
    const { theme, currentContract, currentInterval, contractList, subscribeKLine, unsubscribeKLine } = this.props
    this.releaseTradingView()
    const symbolInfoList = []
    contractList.forEach(contract => {
      const symbolId = formatValue(contract, 'InstrumentID')
      const decimal = getContractPriceDecimalNumber(contract)
      symbolInfoList.push({
        name: symbolId,
        ticker: symbolId,
        exchangeId: formatValue(contract, 'ExchangeID'),
        isInverse: formatValue(contract, 'IsInverse'),
        minmov: 1,
        pricescale: 1 / Math.pow(10, decimal),
        volume_precision: 0,
        session: '24x7'
      })
    })
    this.chartWidget = new Widget(
      'k_chart', formatValue(currentContract, 'InstrumentID'),
      this.getInterval(currentInterval),
      symbolInfoList, 'zh', 'Asia/Shanghai',
      {
        theme: theme === THEME.DAY ? 'Light' : 'Dark',
        customCssUrl: `/chart_style/chart-${theme}.css`,
        overrides: {
          'paneProperties.background': theme === THEME.DAY ? '#ffffff' : '#1f2126'
        }
      },
      getHistoryKLineData,
      (symbolId, exchangeId, resolution, onRealtimeCallback) => {
        subscribeKLine(fromJS({ InstrumentID: symbolId, ExchangeID: exchangeId }), resolution)
        this.onRealtimeCallback = onRealtimeCallback
      },
      (symbolId, exchangeId, resolution) => {
        unsubscribeKLine(fromJS({ InstrumentID: symbolId, ExchangeID: exchangeId }), resolution)
      }
    )
  }

  componentDidMount () {
    this.props.onRef(this)
    const { wsConnectSuccess, currentContract } = this.props
    if (wsConnectSuccess && currentContract) {
      this.initTradingView()
    }
  }

  componentDidUpdate (prevProps, prevState, snapshot) {
    const { theme, wsConnectSuccess, currentContract, currentInterval, kLineData } = this.props
    if ((wsConnectSuccess && !prevProps.wsConnectSuccess && currentContract) ||
      (wsConnectSuccess && !prevProps.currentContract && currentContract)) {
      this.initTradingView()
    }
    if (currentInterval !== prevProps.currentInterval) {
      if (this.chartWidget && this.chartWidget.chartReady) {
        const chart = this.chartWidget.chart()
        const { resolution, chartType } = this.getInterval(currentInterval)
        chart.setResolution(resolution, () => {})
        if (chart.chartType() !== chartType) {
          chart.setChartType(chartType)
        }
      }
    }
    if (theme !== prevProps.theme) {
      this.setTheme(theme)
    }
    if (prevProps.currentContract &&
      formatValue(prevProps.currentContract, 'InstrumentID') !== formatValue(currentContract, 'InstrumentID')) {
      if (this.chartWidget && this.chartWidget.chartReady) {
        const chart = this.chartWidget.chart()
        chart.setSymbol(formatValue(currentContract, 'InstrumentID'), () => {})
      }
    }
    if (kLineData && !is(prevProps.kLineData, kLineData) && this.onRealtimeCallback) {
      console.debug(kLineData.toJS())
      this.onRealtimeCallback(kLineData.toJS())
    }
  }

  /**
   * 获取周期
   */
  getInterval (interval) {
    let chartType
    if (interval === K_INTERVAL_REAL_TIME) {
      chartType = 3
    } else {
      chartType = 1
    }
    const resolution = intervals[interval]
    return { resolution, chartType }
  }

  /**
   * 设置主题
   * @param theme
   */
  setTheme (theme) {
    if (this.chartWidget && this.chartWidget.chartReady) {
      this.chartWidget.changeTheme(theme === THEME.DAY ? 'Light' : 'Dark')
      this.chartWidget.addCustomCSSFile(`/chart_style/chart-${theme}.css`)
      this.chartWidget.applyOverrides({
        'paneProperties.background': theme === THEME.DAY ? '#ffffff' : '#1f2126'
      })
    }
  }

  /**
   * 显示设置弹框
   */
  showSettingDialog () {
    this.showDialog('chartProperties')
  }

  /**
   * 显示指标弹框
   */
  showIndicatorDialog () {
    this.showDialog('insertIndicator')
  }

  /**
   * 显示弹框
   * @param dialogType
   */
  showDialog (dialogType) {
    if (this.chartWidget && this.chartWidget.chartReady) {
      this.chartWidget.closePopupsAndDialogs()
      this.chartWidget.chart().executeActionById(dialogType)
    }
  }

  componentWillUnmount () {
    this.releaseTradingView()
  }

  /**
   * 清除tradingview
   */
  releaseTradingView () {
    if (this.chartWidget) {
      this.chartWidget.remove()
      this.chartWidget = null
    }
  }

  render () {
    return <div id="k_chart" className="trading-view"/>
  }
}

export default TradingView
